package com.yunpeng.aidevice.biz.service.impl;

import com.yunpeng.aidevice.biz.service.IRoleBizService;
import com.yunpeng.aidevice.common.vo.RoleDetailVO;
import com.yunpeng.aidevice.common.vo.RolePermissionVO;
import com.yunpeng.aidevice.common.vo.user.UserRoleVO;
import com.yunpeng.aidevice.dao.constant.DictionariesConstant;
import com.yunpeng.aidevice.dao.service.IPermissionService;
import com.yunpeng.aidevice.dao.service.IRoleService;
import com.yunpeng.aidevice.common.constant.QueryConstants;
import com.yunpeng.common.dto.Result;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.common.enums.QueryOperatorEnum;
import com.yunpeng.common.paging.PagingQueryDTO;
import com.yunpeng.common.paging.query.QueryParam;
import com.yunpeng.aidevice.dao.model.entity.RoleDO;
import com.yunpeng.aidevice.dao.model.relation.RolePermissionDO;
import com.yunpeng.aidevice.dao.model.relation.UserRoleDO;
import com.yunpeng.aidevice.dao.service.IListQueryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * RoleBizServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-15
 */
@Service
public class RoleBizServiceImpl implements IRoleBizService {

    @Resource
    private IListQueryService listQueryService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IPermissionService permissionService;

    @Override
    /**
     * 新增角色
     *
     * @param roleName     角色名称
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> addNew(String roleName, String operatorCode) {
        if (roleService.addNew(roleName, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 删除角色
     *
     * @param roleCode     角色代码
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> remove(String roleCode, String operatorCode) {
        if (roleService.existUserRoleCount(roleCode, null) > 0) {
            return Result.build(ResultCodeEnum.SAVE_DATA_FAILED.getValue(), "存在用户关联角色，请解绑后再删除！");
        }
        if (roleService.remove(roleCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.REMOVE_FAILED);
    }

    @Override
    /**
     * 角色服务端分页列表
     *
     * @param name        名称左匹配
     * @param pageSize    （页数据数量，1-100，默认10）
     * @param currentPage （当前页码，默认1）
     * @return
     */
    public Result<PagingQueryDTO> list(String name, Integer pageSize, Integer currentPage) {
        PagingQueryDTO pagingQueryDTO = new PagingQueryDTO();
        List<QueryParam> queryParams = new ArrayList<>();
        LinkedHashMap<String, String> orderByMap = new LinkedHashMap<>(16);
        //设置查询条件
        if (StringUtils.isNotBlank(name)) {
            queryParams.add(QueryParam.quickSetQueryParam("name", name, QueryOperatorEnum.LEFT_LIKE));
        }
        queryParams.add(QueryParam.quickSetQueryParam("flag", 1, QueryOperatorEnum.EQUALS));
        queryParams.add(QueryParam.quickSetQueryParam("code", DictionariesConstant.INSTANCE.getDefaultRoleName(), QueryOperatorEnum.NOT_EQUALS));
        queryParams.add(QueryParam.quickSetQueryParam("code", DictionariesConstant.INSTANCE.getAdminRoleName(), QueryOperatorEnum.NOT_EQUALS));
        queryParams.add(QueryParam.quickSetQueryParam("tenant_code", DictionariesConstant.INSTANCE.getDefaultTenantCode(), QueryOperatorEnum.EQUALS));
        //设置排序
        orderByMap.put("update_time", "desc");
        orderByMap.put("id", "desc");
        pagingQueryDTO.setCurrentPage(currentPage);
        pagingQueryDTO.setPageSize(pageSize);
        pagingQueryDTO.setConditionList(queryParams);
        pagingQueryDTO.setSortColumnMap(orderByMap);
        PagingQueryDTO resultData = listQueryService.query(pagingQueryDTO, QueryConstants.QUERY_ROLE_LIST_4_SERVICE_SIDE, null);
        return Result.success(resultData);
    }

    @Override
    /**
     * 绑定权限到角色
     *
     * @param roleCode       角色代码
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> bindPermission(String roleCode, String permissionCode, String operatorCode) {
        if (roleService.bindPermission(roleCode, permissionCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 解除权限绑定角色
     *
     * @param roleCode       角色代码
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Result<Void> unbindPermission(String roleCode, String permissionCode, String operatorCode) {
        if (roleService.unbindPermission(roleCode, permissionCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 用户绑定角色
     *
     * @param roleCode     角色代码
     * @param userCode     用户代码
     * @param startTime    起始生效时间
     * @param endTime      生效截止时间
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> userBindRole(String roleCode, String userCode, Date startTime, Date endTime, String operatorCode) {
        if (roleService.userBindRole(roleCode, userCode, startTime, endTime, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 用户解除角色
     *
     * @param roleCode     角色代码
     * @param userCode     用户代码
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> userUnbindRole(String roleCode, String userCode, String operatorCode) {
        if (roleService.userUnBindRole(roleCode, userCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 角色详情数据视图
     *
     * @param roleCode 角色代码
     * @return
     */
    public Result<RoleDetailVO> detailInfo(String roleCode) {
        RoleDO roleDO = roleService.getByCode(roleCode);
        if (roleDO == null || roleDO.getId() == null) {
            return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
        }
        RoleDetailVO roleDetailVO = new RoleDetailVO();
        roleDetailVO.setCode(roleDO.getCode());
        roleDetailVO.setName(roleDO.getName());

        List<UserRoleDO> userRoleDOList = roleService.queryUserRoleListByRole(roleCode);
        List<RolePermissionDO> rolePermissionDOList = permissionService.queryRolePermissionListByRole(roleCode);
        if (rolePermissionDOList != null && rolePermissionDOList.size() > 0) {
            roleDetailVO.setOperatePermissions(rolePermissionDOList.stream().map(t -> new RolePermissionVO(t.getRoleCode(), t.getRoleName(), t.getPermissionCode(), t.getPermissionName())).collect(Collectors.toList()));
        }
        if (userRoleDOList != null && userRoleDOList.size() > 0) {
            roleDetailVO.setUsers(userRoleDOList.stream().map(t -> new UserRoleVO(t.getUserCode(), t.getUserName(), t.getRoleCode(), t.getRoleName(), t.getStartDate(), t.getEndDate())).collect(Collectors.toList()));
        }
        return Result.success(roleDetailVO);
    }
}
